/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kreig133.controller;

import com.kreig133.analytic.builder.AnalyticBuildDirector;
import com.kreig133.analytic.extractors.ExperimentExtractor;
import com.kreig133.analytic.extractors.Parser;
import com.kreig133.graphic.MakeGraphic;
import com.kreig133.spine.abstractmodel.AbstractState;
import com.kreig133.spine.builder.ExperimentBuildDirector;
import com.kreig133.spine.builder.ModelBuildDirector;
import com.kreig133.spine.interfaces.ExperimentResultSaver;
import com.kreig133.spine.simplemodel.SimpleExperiment;
import com.kreig133.spine.simplemodel.SimpleSpine;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JPanel;

/**
 *
 * @author eshangareev
 */
public class Controller {

    private static JFileChooser jfc = new JFileChooser();

    static {
        jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    }

    /**
     * Создает диалоговое окно, в котором пользователь выбирает файл.
     * Возращает путь к файлу выбранного файла, иначе null.
     * @param comp 
     * @return 
     */
    public static String openFile(JComponent comp) {
        jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        if (jfc.showOpenDialog(comp) == JFileChooser.APPROVE_OPTION) {
            return jfc.getSelectedFile().getAbsolutePath();
        }
        return null;
    }

    /**
     * Обработка данных реальных экспериментов, возращается график.
     * @param settingFile - путь к файлу с настройками
     * @param aimFile - путь к файлу с данными реальных эксприментов
     * @return 
     */
    public static JPanel realDataProcessing(final String settingFile, final String aimFile) {
        try {
            Parser p = new Parser();
            p.setFile(new File(aimFile));
            AnalyticBuildDirector director = new AnalyticBuildDirector(p, new File(settingFile));

            return MakeGraphic.drawGraphic("RealData", director.construct().getProcessedData());
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    /**
     * Просмотр результатов эксперимента.
     * @param settingFile - путь к файлу с настройками обработчика
     * @param aimFile - путь к файлу с результатами эксперимента
     * @return 
     */
    public static JPanel experimentResultViewer(final String settingFile, final String aimFile) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(aimFile));
            Map<Double, List<AbstractState>> result = (Map<Double, List<AbstractState>>) ois.readObject();

            ExperimentExtractor expExtractor = new ExperimentExtractor(result);
            AnalyticBuildDirector director = new AnalyticBuildDirector(expExtractor, new File(settingFile));
            Map<Double, Double> processedData = director.construct().getProcessedData();


            return com.kreig133.graphic.MakeGraphic.drawGraphic("ExperimentResult", processedData);

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }
    
    /**
     * Моделирование эксперимента.
     * @param comp
     * @param settingFile
     * @param aimFile
     * @return 
     */

    public static JPanel experimentProcess(final JComponent comp, final String settingFile, final String aimFile) {
        ExperimentBuildDirector director = new ExperimentBuildDirector(new File(settingFile));
        SimpleExperiment experiment = director.construct();
        ModelBuildDirector modelDirector = new ModelBuildDirector(new File(aimFile));
        SimpleSpine model = modelDirector.construct();

        ExperimentResultSaver saver = new ExperimentResultSaver() {

            @Override
            public void saveResult(Map<Double, List<AbstractState>> result) {
                if (!(jfc.showSaveDialog(comp) == JFileChooser.APPROVE_OPTION)) {
                    return;
                }
                File target = jfc.getSelectedFile();
                ObjectOutputStream oos = null;

                try {
                    oos = new ObjectOutputStream(new FileOutputStream(target));
                    oos.writeObject(result);
                } catch (IOException ex) {
                    ex.printStackTrace();
                } finally {
                    try { oos.close();
                    } catch (IOException ex) {}
                }
            }
        };
        model.doExperiment(experiment, saver);
        return null;
    }

    public static JPanel process(TaskEnum task, final JComponent comp, final String settingFile, final String aimFile) {
        if (settingFile == null || aimFile == null) {
            return null;
        }

        switch (task) {
            case ExperimentView:
                return experimentResultViewer(settingFile, aimFile);
            case ProcessModel:
                return experimentProcess(comp, settingFile, aimFile);
            case RealDataView:
                return realDataProcessing(settingFile, aimFile);
        }

        return null;
    }
}
